﻿using ManagementApi.Models.App;
using ManagementApi.Models.Manage.CheckIn;
using Modules;
using Modules.CheckIn;
using Modules.CheckIn.Entitys;
using Modules.Corp;
using Modules.Person;
using Modules.Project;
using Modules.Project.Entitys;
using Modules.System.Settings;
using Modules.System.Settings.Entitys;
using PetaPoco;
using PmSoft;
using PmSoft.DBContext;
using PmSoft.Entity;
using PmSoft.Exceptions;
using PmSoft.Utilities;

namespace ManagementApi.Services
{
    [UseDI(ServiceLifetime.Scoped)]
    public class AppService
    {
        private readonly IConfiguration configuration;
        private readonly ProjectGroupMemberService projectGroupMemberService;
        private readonly ProjectService projectService;
        private readonly ProjectGroupService projectGroupService;
        private readonly CorpService corpService;
        private readonly PersonService personService;
        private readonly DefaultDbContext dbContext;

        public AppService(IConfiguration configuration, ProjectGroupMemberService projectGroupMemberService, ProjectService projectService, ProjectGroupService projectGroupService, CorpService corpService, PersonService personService, DefaultDbContext dbContext)
        {
            this.configuration = configuration;
            this.projectGroupMemberService = projectGroupMemberService;
            this.projectService = projectService;
            this.projectGroupService = projectGroupService;
            this.corpService = corpService;
            this.personService = personService;
            this.dbContext = dbContext;
        }

        /// <summary>
        /// 生成token
        /// </summary>
        /// <param name="securityId"></param>
        /// <param name="userType"></param>
        /// <param name="cardNumber"></param>
        /// <returns></returns>
        public string GetToken(int securityId, UserType userType, string cardNumber)
        {
            //根据用户信息,生成token  ,源格式为:安全id|usertype|身份证|timestamp
            PersonInfo? personInfo = personService.GetPersonByCardNo(cardNumber);
            if (personInfo == null)
                throw new BusinessException("没有查询到人员信息");
            string value = $"{securityId}|{userType}|{cardNumber}|{DateTime.Now.AddDays(7)}|{personInfo.PersonId}";
            return EncryptionUtility.SymmetricEncrypt(SymmetricEncryptType.Rijndael, value);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="personId"></param>
        /// <param name="isCheckInReport">是否统计考勤 </param>
        /// <returns></returns>
        public IEnumerable<ProjectAppDto> GetProjects(int personId, bool isCheckInReport = false)
        {
            IEnumerable<ProjectGroupMember> projectGroupMembers = projectGroupMemberService.GetProjectGroupMembersByPersonId(personId);
            var projects = projectService.GetProjects(projectGroupMembers.Select(a => a.ProjectId));
            var groups = projectGroupService.GetProjectGroups(projectGroupMembers.Select(a => a.GroupId));
            var corps = corpService.GetCorpInfos(projectGroupMembers.Select(a => a.CorpId));
            List<ProjectAppDto> dtos = new List<ProjectAppDto>();

            //要改
            //IEnumerable<CheckinCountMonth> checkinCountMonths = new List<CheckinCountMonth>();
            //if (isCheckInReport)
            //{
            //    checkinCountMonths = checkinCountMonthService.GetCheckInDetailCountByPersonAndMember(projectGroupMembers.Select(a => a.Id), personId);
            //}

            foreach (var item in projectGroupMembers)
            {
                ProjectAppDto dto = new ProjectAppDto();
                dto.ProjectId = item.ProjectId;
                dto.ProjectGroupMemberId = item.Id;
                dto.WorkType = item.Type.GetDescription();
                var projectInfo = projects.Where(a => a.ProjectId == item.ProjectId).FirstOrDefault();
                if (projectInfo != null)
                {
                    dto.ProjectName = projectInfo.Name;
                    dto.ProjectAddress = projectInfo.Address;
                    //dto.Lat = projectInfo.Lat;
                    //dto.Lng = projectInfo.Lng;
                }
                if (groups != null)
                    dto.GroupName = groups.FirstOrDefault(a => a.GroupId == item.GroupId)?.Name ?? string.Empty;
                if (corps != null)
                    dto.CorpName = corps.FirstOrDefault(a => a.CorpId == item.CorpId)?.Name ?? string.Empty;
                //考勤统计
                //要改
                //if (checkinCountMonths != null && checkinCountMonths.Count() > 0)
                //{
                //    CkeckInDto ckeckInDto = new CkeckInDto()
                //    {
                //        CheckInAllDays = checkinCountMonths.Where(a => a.MemberId == item.Id).Sum(a => a.CheckinCount),
                //        CheckInThisMonmthDays = checkinCountMonths.Where(a => a.MemberId == item.Id && a.Month == Convert.ToDateTime($"{DateTime.Now.ToString("yyyy-MM")}-01").Date).Sum(a => a.CheckinCount)
                //    };
                //    dto.ckeckIn = ckeckInDto;
                //}

                dtos.Add(dto);
            }
            return dtos;
        }

        public IEnumerable<CheckInDetailDto> GetCheckInDetails(string tableName, int projectGroupMemberId, int personId)
        {
            Sql sql = Sql.Builder.Append($"select * from {tableName} where person_id=@0 and member_id=@1 and status=1 order by create_time desc", personId, projectGroupMemberId);
            IEnumerable<CheckInDetail> checkInDetails = dbContext.Query<CheckInDetail>(sql);
            List<CheckInDetailDto> checkInDetailDtos = new List<CheckInDetailDto>();
            foreach (var item in checkInDetails)
            {
                checkInDetailDtos.Add(item.AsAppDto());
            }
            return checkInDetailDtos;
        }

        public CkeckInDto? GetCheckInDetailsThisMonth(int projectGroupMemberId, int personId)
        {
            Sql sql = Sql.Builder.Append($"select (select sum(checkin_count) from checkin_count_month where person_id=@0 AND member_id=@1) as checkInAllDays,(select checkin_count from checkin_count_month where person_id=@0 AND member_id=@1 AND month=@2) as checkInThisMonmthDays", personId, projectGroupMemberId, DateTime.Now.ToString("yyyy-MM-01"));
            return dbContext.Query<CkeckInDto>(sql).FirstOrDefault();
        }
    }
}